home *** CD-ROM | disk | FTP | other *** search
- /* TempoController.c */
- /*****************************************************************************/
- /* */
- /* Out Of Phase: Digital Music Synthesis on General Purpose Computers */
- /* Copyright (C) 1994 Thomas R. Lawrence */
- /* */
- /* This program is free software; you can redistribute it and/or modify */
- /* it under the terms of the GNU General Public License as published by */
- /* the Free Software Foundation; either version 2 of the License, or */
- /* (at your option) any later version. */
- /* */
- /* This program is distributed in the hope that it will be useful, */
- /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
- /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
- /* GNU General Public License for more details. */
- /* */
- /* You should have received a copy of the GNU General Public License */
- /* along with this program; if not, write to the Free Software */
- /* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
- /* */
- /* Thomas R. Lawrence can be reached at tomlaw@world.std.com. */
- /* */
- /*****************************************************************************/
-
- #include "MiscInfo.h"
- #include "Audit.h"
- #include "Debug.h"
- #include "Definitions.h"
-
- #include "TempoController.h"
- #include "Memory.h"
- #include "LinearTransition.h"
- #include "PlayTrackInfoThang.h"
-
-
- #define MINBPM (Double2LargeBCD(1))
-
-
- struct TempoControlRec
- {
- LargeBCDType DefaultBeatsPerMinute;
- LargeBCDType CurrentBeatsPerMinute;
- struct LinearTransRec* BeatsPerMinuteChange;
- long BeatsPerMinuteChangeCountdown;
- };
-
-
- /* create a new tempo control record */
- TempoControlRec* NewTempoControl(LargeBCDType DefaultBeatsPerMinute)
- {
- TempoControlRec* Tempo;
-
- Tempo = (TempoControlRec*)AllocPtrCanFail(sizeof(TempoControlRec),"TempoControlRec");
- if (Tempo == NIL)
- {
- FailurePoint1:
- return NIL;
- }
- Tempo->DefaultBeatsPerMinute = DefaultBeatsPerMinute;
- Tempo->CurrentBeatsPerMinute = Tempo->DefaultBeatsPerMinute;
- Tempo->BeatsPerMinuteChange = NewLinearTransition(0,0,1);
- if (Tempo->BeatsPerMinuteChange == NIL)
- {
- FailurePoint2:
- ReleasePtr((char*)Tempo);
- goto FailurePoint1;
- }
- Tempo->BeatsPerMinuteChangeCountdown = 0;
- return Tempo;
- }
-
-
- /* dispose of a tempo control record */
- void DisposeTempoControl(TempoControlRec* Tempo)
- {
- CheckPtrExistence(Tempo);
- DisposeLinearTransition(Tempo->BeatsPerMinuteChange);
- ReleasePtr((char*)Tempo);
- }
-
-
- /* update the tempo control & return the new value */
- LargeBCDType TempoControlUpdate(TempoControlRec* Tempo, long NumTicks)
- {
- CheckPtrExistence(Tempo);
- if (NumTicks < Tempo->BeatsPerMinuteChangeCountdown)
- {
- Tempo->CurrentBeatsPerMinute = LinearTransitionUpdateMultiple(
- Tempo->BeatsPerMinuteChange,NumTicks);
- Tempo->BeatsPerMinuteChangeCountdown -= NumTicks;
- }
- else if (Tempo->BeatsPerMinuteChangeCountdown > 0)
- {
- Tempo->CurrentBeatsPerMinute = LinearTransitionUpdateMultiple(
- Tempo->BeatsPerMinuteChange,Tempo->BeatsPerMinuteChangeCountdown);
- Tempo->BeatsPerMinuteChangeCountdown = 0;
- }
- return Tempo->CurrentBeatsPerMinute;
- }
-
-
- /* reset tempo to default value */
- void TempoControlRestoreDefault(TempoControlRec* Tempo)
- {
- CheckPtrExistence(Tempo);
- Tempo->CurrentBeatsPerMinute = Tempo->DefaultBeatsPerMinute;
- Tempo->BeatsPerMinuteChangeCountdown = 0;
- }
-
-
- /* set the tempo to the specified number of beats per minute */
- void TempoControlSetBeatsPerMinute(TempoControlRec* Tempo,
- LargeBCDType NewBeatsPerMinute)
- {
- CheckPtrExistence(Tempo);
- Tempo->CurrentBeatsPerMinute = NewBeatsPerMinute;
- if (Tempo->CurrentBeatsPerMinute < MINBPM)
- {
- Tempo->CurrentBeatsPerMinute = MINBPM;
- }
- Tempo->BeatsPerMinuteChangeCountdown = 0;
- }
-
-
- /* adjust the tempo by adding the specified value to it */
- void TempoControlAdjustBeatsPerMinute(TempoControlRec* Tempo,
- LargeBCDType IncrementBeatsPerMinute)
- {
- CheckPtrExistence(Tempo);
- Tempo->CurrentBeatsPerMinute += IncrementBeatsPerMinute;
- if (Tempo->CurrentBeatsPerMinute < MINBPM)
- {
- Tempo->CurrentBeatsPerMinute = MINBPM;
- }
- Tempo->BeatsPerMinuteChangeCountdown = 0;
- }
-
-
- /* sweep the tempo to a new value */
- void TempoControlSweepToNewValue(TempoControlRec* Tempo,
- LargeBCDType NewBPM, SmallExtBCDType NumBeatsToReach)
- {
- CheckPtrExistence(Tempo);
- if (NewBPM < MINBPM)
- {
- NewBPM = MINBPM;
- }
- if (NumBeatsToReach < 0)
- {
- NumBeatsToReach = 0;
- }
- Tempo->BeatsPerMinuteChangeCountdown = SmallExtBCD2Double(NumBeatsToReach)
- * (DURATIONUPDATECLOCKRESOLUTION / 4);
- RefillLinearTransition(Tempo->BeatsPerMinuteChange,Tempo->CurrentBeatsPerMinute,
- NewBPM,Tempo->BeatsPerMinuteChangeCountdown);
- }
-
-
- /* sweep the tempo to a new value relative to the current value */
- void TempoControlSweepToAdjustedValue(TempoControlRec* Tempo,
- LargeBCDType AdjustBPM, SmallExtBCDType NumBeatsToReach)
- {
- CheckPtrExistence(Tempo);
- TempoControlSweepToNewValue(Tempo,Tempo->CurrentBeatsPerMinute + AdjustBPM,
- NumBeatsToReach);
- }
-